/*

* 文件名：func.hpp

* 描述： 功能函数声明及定义

* 编写人：Lil_leap

* 编写时间：2022-12-05

* 修改人：Dexter

* 修改时间：2022-12-10

*/
#ifndef _FUNC_HPP
#define _FUNC_HPP

#include<bits/stdc++.h>

using namespace std;

extern void inquiry();
//查询功能函数
extern void aqi();
//aqi计算函数
extern void sort();
//排序函数
extern int date_counter(int date);
//日期所对应的天数
extern int next_date(string a);
//下一天的日期
extern void input(string input_filename);
//依照文件名输入数据
extern void date_read();
//数据读取函数
extern int type_cor(string a);
//数据类型对应
extern int days2date(int n);
//将天数转换为日期


void inquiry()
{
    string city;
    int date,time,i,temp,city_num;
    queue<int> typeq,type_tmp,days;
    
    //数据输入
    cout<<"请输入城市名称（中文）："<<endl;
    cin>>city;
    cout<<"请输入查询日期（无具体日期请填-1）："<<endl;
    cin>>date;//无就填-1
    cout<<"请输入查询时间（无具体时间请填-1）："<<endl;    
    cin>>time;
    
    //city定位
    for(city_num = 0;city_num < 375; city_num++)
        if(city == cities_names[city_num])     break;
    
    cout<<"输入查询指标类型（数字） 以-1结束"<<endl;
    while(cin>>temp&&temp != -1)    typeq.push(temp);//如果无type条件 typeq为空
    
    //typeq为空 全查一遍
    if(typeq.empty())
    {
        for(int i = 0;i < 15;i++)   typeq.push(i);
    }
    cout<<city<<endl;
    
    int front = typeq.front();
    // cout<<"          "<<" "<<"          ";
    // 输出表头
    cout<<setw(10)<<"date"<<setw(10)<<"time";
    while(1)
    {
        cout<<setw(10)<<type[typeq.front()];
        typeq.push(typeq.front());
        typeq.pop();
        if(typeq.front() == front) break;
    }
    cout<<endl;

    if(date == -1)
    {
        for(int i = 1 ; i <= 20; i++)    days.push(i);
    }
    else    days.push(date_counter(date));    //否则只输出指定日期
    

    if(time == -1)  time = 8;//如果time为缺省值 输出每天8点的数据


    while (!(days.empty()))
    {
        type_tmp = typeq;
        cout<<setw(10)<<days2date(days.front())<<setw(10)<<time;
        while(!(type_tmp.empty()))
        {
            cout<<setw(10)<<cities[city_num].num[days.front()][time].a[type_tmp.front()];
            type_tmp.pop();
        }
        cout<<endl;
        days.pop();
    }
}

/* AQI: 0~50、51~100、101~150、151~200、201~300、>300 */

void aqi()
{
    string city;
    cout<<"请输入城市名称："<<endl;
    cin>>city;
    int city_num;
    //城市定位
    for(city_num = 0;city_num < 375; city_num++)    
        if(city == cities_names[city_num])     break;
    
    int date_begin,date_end;
    cout<<"请输入起始日期（例20200101）："<<endl;
    cin>>date_begin;
    cout<<"请输入终止日期（例20200101）："<<endl;
    cin>>date_end;
    if(date_begin > date_end)
    {
        cout<<"Input Error!";
        exit(1);
    }
    //日期对应天数计算
    int days_begin = date_counter(date_begin),days_end = date_counter(date_end),days = days_end - days_begin + 1;
    
    int aqi[days+1][25],aqi_level[7] = {0};
    int max=cities[city_num].num[days_begin][0].a[0],min = cities[city_num].num[days_begin][0].a[0];
    unsigned long long int sum = 0;
    for(int i = 0;i<days;i++)
        for(int t = 0;t<24;t++)
        {
            aqi[i][t] = cities[city_num].num[days_begin + i][t].a[0];
            //AQI最大最小值计算
            max = aqi[i][t] > max ? aqi[i][t] : max;
            if(aqi[i][t] != 0)  min = aqi[i][t] < min ? aqi[i][t] : min;
            //AQI求和计算平均值
            sum += aqi[i][t];
            /* AQI: 0~50、51~100、101~150、151~200、201~300、>300 */
            //AQI等级分布计数
            if(aqi[i][t]>0&&aqi[i][t]<=50)         aqi_level[1] ++;
            else if(aqi[i][t]>=51&&aqi[i][t]<=100)  aqi_level[2] ++;
            else if(aqi[i][t]>=101&&aqi[i][t]<=150) aqi_level[3] ++;
            else if(aqi[i][t]>=151&&aqi[i][t]<=200) aqi_level[4] ++;
            else if(aqi[i][t]>=201&&aqi[i][t]<=300) aqi_level[5] ++;
            else if(aqi[i][t]>=300)                 aqi_level[6] ++;

        }
        double average = sum/(days*24);

        cout<<"---------------------------------------------------------------"<<endl;
        cout<<"城市:\t"<<city<<endl;
        cout<<"时间范围:\t"<<date_begin<<"-"<<date_end<<endl;
        cout<<"最大值:\t"<<max<<endl;
        cout<<"最小值:\t"<<min<<endl;
        cout<<"AQI平均值:\t"<<average<<endl;
        cout<<"AQI等级分布:"<<endl;
        cout<<"AQI = 0~50\t"<<aqi_level[1]<<endl
            <<"AQI = 51~100\t"<<aqi_level[2]<<endl
            <<"AQI = 101~150\t"<<aqi_level[3]<<endl
            <<"AQI = 151~200\t"<<aqi_level[4]<<endl
            <<"AQI = 201~300\t"<<aqi_level[5]<<endl
            <<"AQI > 300\t"<<aqi_level[6]<<endl;

}
// struct aqi_average
// {
//     string city_name;
//     double aqi_aver;
// };
// unsigned long long int sum = 0;
// aqi_average aqi_city[375];


//结构体排序比较函数
bool cmp(aqi_average &a,aqi_average &b)
{
    if(a.aqi_aver<b.aqi_aver)   return true;
    else                        return false;
}

void sort()
{
    aqi_average aqi_city[375];
    int date_begin,date_end;
    cout<<"请输入起始日期（例20200101）："<<endl;
    cin>>date_begin;
    cout<<"请输入终止日期（例20200101）："<<endl;
    cin>>date_end;
    //日期对应天数计算
    int days_begin = date_counter(date_begin),days_end = date_counter(date_end),days = days_end - days_begin + 1;
    
    if(date_begin > date_end)
    {
        cout<<"Input Error!";
        exit(1);
    }

    
    for(int c = 0;c < 375;c++)
    {
        unsigned long long int sum = 0;
        aqi_city[c].city_name = cities[c].name;
        for(int i = 0;i < days;i++)
            for(int t = 0;t < 24 ;t++)
                //求和
                sum += cities[c].num[days_begin + i][t].a[0];
        //求平均值
        aqi_city[c].aqi_aver = sum/(days*24);
    }
    //利用cmp函数排序
    sort(aqi_city,aqi_city+375,cmp);

    cout<<"AQI均值前十城市："<<endl;
    int i = 0,t = 0;
    while(t<10)
    {
        if(aqi_city[i].aqi_aver != 0)
        {
            t++;
            cout<<aqi_city[i].city_name<<"\t"<<aqi_city[i].aqi_aver<<endl;
        }
        i++;
    }
    // for(int i = 0;i < 10;i++)
    // {
    //     cout<<aqi_city[i].city_name<<"\t"<<aqi_city[i].aqi_aver<<endl;
    // }
    cout<<"---------------------------------------------------------------"<<endl;
    cout<<"AQI均值后十城市："<<endl;
    for(int i = 374;i >= 364;i--)
    {
        cout<<aqi_city[i].city_name<<"\t"<<aqi_city[i].aqi_aver<<endl;
    }
}

void input(string input_filename)
{
    ifstream fin;
    //依据文件名输入
    fin.open(input_filename.c_str());
    if (fin.fail())
    {
        cout << "Failed to open " << input_filename << endl;
        exit(1);
    }

    //读取到文件尾
    while(!fin.eof())
    {
        string str_line;
        while(getline(fin, str_line))
        {
            string str_tmp;
            stringstream ss(str_line);
            for(int i = 0;i<NUM_COLUMNS;i++)
            {
                getline(ss, str_tmp, ',');
                str_columns[i] = str_tmp;
                if(i>=3) cities[i-3].num[date_counter(atoi(str_columns[0].c_str()))][atoi(str_columns[1].c_str())].a[type_cor(str_columns[2])] = atof(str_columns[i].c_str());
            }
        }
    }
}



int days2date(int n)
{
	int day[12]={31,28,31,30,31,30,31,31,30,31,30,31};
	int month,date;
    string month_s,day_s;
	int i;
	if(n<32)
	{
		month=1;
		date=n;
	}
	else
	{
		for(i=0;i<12;i++)
		{
			n=n-day[i];
			if(i==0&&n>0&&n<29) break;
			else
			{
				if(i!=0&&n>0&&n<32) 
				break;
			}
        }
        month=i+2;
        date=n;
    }
    date = 20210000 + month*100 + date;
    return date;
}

int date_counter(int date)
{

    int y=date/10000,m=date%10000/100,d=date%100;
    int ans = 0;
    int n = 0;
    for(int i=1;i<=m;i++)
    {
        if(i==m)
        {
            ans+=d;
            break;
        }
        else if(i!=m&&(i==1||i==3||i==5||i==7||i==8||i==10||i==12))
            {
                ans+=31;
            }
        else if(i!=m&&(i==4||i==6||i==9||i==11))
            {
                ans+=30;
            }
        else if(i!=m&&i==2)
            {
                ans=ans+28;
            }
    }
    return ans;
}

int next_date(string a)
{
	int m,d;
    m = 10*(a[4]-48)+a[5]-48;
    d = 10*(a[6]-48)+a[7]-48;
	if(((m==1||m==3||m==5||m==7||m==8||m==10||m==12)&&d==31)||(!(m==1||m==3||m==5||m==7||m==8||m==10||m==12)&&d==30))
	{
		d=1;
		m++;
	}
	else if(m==2&&d==28)
	{
		m=3;
		d=1;
	}
	else 
	{
			d++;
	}
	a[4] = m/10+48;a[5] = m%10+48;
	a[6] = d/10+48;a[7] = d%10+48;
	return atoi(a.c_str());
}

int type_cor(string a)
{
    int i = 0;
    for(i;i < 15; i++)
    {
        if(a == type[i])    return i;
    }
    return i;
}

void date_read()
{
    for(int i = 20210101;i<=20211231;i=next_date(to_string(i)))//数据读取
    {
        string str_date = to_string(i);
        //将int转换为string
        string input_filename = "./data_AQI2021/china_cities_" + str_date + ".csv";
        input(input_filename);
    }
    //城市名字存储
    for(int i = 0; i < 375; i++)
    {
        cities[i].name = cities_names[i];
    }
}


#endif